home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection 1998 Fall: Game Toolkit / Disc.iso / SDKs / PCI Driver Development Kit / • Samples / Driver Samples / Video samples / GDX 950717 / GDX / GraphicsCoreStatus.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-20  |  70.1 KB  |  1,796 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        GraphicsCoreStatus.c
  3.  
  4.     Contains:    Implements the 'core' portions of the graphics Status calls.
  5.  
  6.     Written by:    Sean Williams, Kevin Williams
  7.  
  8.     Copyright:    © 1994-1995 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <2>     7/17/95    SW        In GraphicsCore GetConnection(), now reporting new constants for
  13.                                      16, 19, and 21 inch color monitors.
  14.          <1>     4/15/95    SW        First Checked In
  15.  
  16. */
  17.  
  18. #include "GraphicsCoreStatus.h"
  19. #include "GraphicsCorePriv.h"
  20. #include "GraphicsPriv.h"
  21. #include "GraphicsCoreUtils.h"
  22. #include "GraphicsHAL.h"
  23. #include "GraphicsOSS.h"
  24.  
  25. #include <DriverServices.h>
  26. #include <Video.h>
  27.  
  28. // Forward declarations
  29. static Boolean GammaTableApplicable(GammaTableID gammaTableID, DisplayCode displayCode);
  30.  
  31. typedef GDXErr RetrieveGammaFunction(ByteCount *size, char *name, GammaTbl *gammaTbl);
  32. static RetrieveGammaFunction RetrieveGammaStandard;
  33. static RetrieveGammaFunction RetrieveGammaPageWhite;
  34. static RetrieveGammaFunction RetrieveGammaGray;
  35. static RetrieveGammaFunction RetrieveGammaRubik;
  36. static RetrieveGammaFunction RetrieveGammaNTSCPAL;
  37. static RetrieveGammaFunction RetrieveGammaCSCTFT;
  38.  
  39.  
  40.  
  41. //=====================================================================================================
  42. //
  43. // GraphicsCoreGetMode()
  44. //    This routine returns the current relative pixel depth, current page, and the base address of the
  45. //    frame buffer for the current page.
  46. //
  47. //=====================================================================================================
  48. GDXErr GraphicsCoreGetMode(VDPageInfo *pageInfo)
  49. {
  50.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData() ;
  51.     GDXErr err = kGDXErrUnknownError;                                // Assume failure
  52.     
  53.     pageInfo->csMode = (SInt16) coreData->depthMode;
  54.     pageInfo->csPage = coreData->currentPage;
  55.     pageInfo->csBaseAddr = coreData->baseAddress;
  56.     
  57.     err = kGDXErrNoError ;                                            // Everything Okay
  58.         
  59. ErrorExit:
  60.  
  61.     return (err);
  62. }
  63.  
  64.  
  65.  
  66. //=====================================================================================================
  67. //
  68. // GraphicsCoreGetEntries()
  69. //    This routine must return the specified number of consecutive CLUT entries, starting with the
  70. //    specified first entry.  If gamma table correction is used, the values returned may not be the same
  71. //    as the values orignally passed by cscSetEntries.  If the value of csStart is 0 or positive, the
  72. //    routine must return csCount entries starting at that position.  If it is -1, the routine must
  73. //    access the contents of the 'value' fields in csTable to determine which entries are to be returned.
  74. //    Both csStart and csCount are zero based; their values are l less than the desired amount.
  75. //
  76. //    Although direct video modes do not have logical color tables, the cscGetEntries status routine
  77. //    should continue to return the current contents of the CLUT, just as it would in an indexed mode.
  78. //
  79. //=====================================================================================================
  80. GDXErr GraphicsCoreGetEntries(VDSetEntryRecord *setEntry)
  81. {
  82.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData() ;
  83.     GDXErr err = kGDXErrUnknownError;                                // Assume failure
  84.  
  85.     SInt16 startPosition;
  86.     SInt16 numberOfEntries;
  87.     Boolean sequential;
  88.  
  89.         
  90.     // Make sure that 'setEntry' is pointing to a valid 'VDSetEntryRecord'.  Additionally, extract
  91.     // the 'startPosition' and 'numberOfEntries' from the 'VDSetEntryRecord', and determine if this
  92.     // is a 'Sequential' or 'Indexed' flavor.
  93.     
  94.     err = GraphicsUtilCheckSetEntry(setEntry, coreData->bitsPerPixel, &startPosition, &numberOfEntries, 
  95.             &sequential);
  96.     
  97.     if (err)
  98.         goto ErrorExit;
  99.  
  100.     err = GraphicsHALGetCLUT(setEntry->csTable, startPosition, numberOfEntries, sequential,
  101.             coreData->depthMode);
  102.  
  103.     if (err)
  104.         goto ErrorExit;
  105.  
  106.     err = kGDXErrNoError ;                                            // Everything Okay
  107.         
  108. ErrorExit:
  109.  
  110.     return (err);
  111. }
  112.  
  113.  
  114.  
  115. //=====================================================================================================
  116. //
  117. // GraphicsCoreGetPages()
  118. //    This returns the total number of graphics pages available in the specified relative pixel depth.
  119. //    This is a counting number (not zero based).
  120. //
  121. //    For this routine, the relevant fields of the 'VDPageInfo' structure are as follows:
  122. //            ->    csMode            relative depth mode for which the page count is desired
  123. //            <-    csPage            Number of pages supported at the specified relative depth mode
  124. //
  125. //=====================================================================================================
  126. GDXErr GraphicsCoreGetPages(VDPageInfo *pageInfo)
  127. {
  128.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData() ;
  129.     GDXErr err = kGDXErrUnknownError;                                // Assume failure
  130.  
  131.     SInt16 pageCount;
  132.             
  133.     err = GraphicsHALGetPages(coreData->displayModeID, pageInfo->csMode, &pageCount);
  134.     if (err)
  135.         goto ErrorExit;
  136.     
  137.     pageInfo->csPage = pageCount;                                    // Report the number of pages
  138.     
  139.     err = kGDXErrNoError ;                                            // Everything Okay
  140.         
  141. ErrorExit:
  142.  
  143.     return (err);
  144. }
  145.  
  146.  
  147.  
  148. //=====================================================================================================
  149. //
  150. // GraphicsCoreGetBaseAddress()
  151. //    This returns the base address of a specified page for the current DisplayModeID and DepthMode. 
  152. //    This allows video pages to be written to even when not displayed.
  153. //
  154. //    For this routine, the relevant fields of the 'VDPageInfo' structure are as follows:
  155. //            ->    csPage            page number ( 0 based ).  Return the base address for this page
  156. //            <-    csBaseAddr        base address of desired page
  157. //
  158. //=====================================================================================================
  159. GDXErr GraphicsCoreGetBaseAddress(VDPageInfo *pageInfo)
  160. {
  161.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData() ;
  162.     GDXErr err = kGDXErrUnknownError;                                // Assume failure
  163.     
  164.     pageInfo->csBaseAddr = NULL;                                    // Assume failure
  165.     
  166.     err = GraphicsHALGetBaseAddress( pageInfo->csPage, (char **)&pageInfo->csBaseAddr );
  167.     if (err)
  168.         goto ErrorExit;
  169.  
  170.     err = kGDXErrNoError ;                                            // Everything Okay
  171.         
  172. ErrorExit:
  173.  
  174.     return (err);
  175. }
  176.  
  177.  
  178.  
  179. //=====================================================================================================
  180. //
  181. // GraphicsCoreGetGray()
  182. //    This routine must returns a value indicating whether the cscSetEntries routine has been conditioned
  183. //    to fill a card's CLUT with actual color or with the luminance-equivalent gray tones.  For actual
  184. //    colors (the default case), the value return csMode is 0; for gray tones it is 1.
  185. //
  186. //=====================================================================================================
  187. GDXErr GraphicsCoreGetGray(VDGrayRecord *gray)
  188. {
  189.  
  190.     GDXErr err = kGDXErrUnknownError;                                // Assume failure
  191.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData() ;
  192.     
  193.     if (coreData->luminanceMapping)        
  194.         gray->csMode = 1;
  195.     else
  196.         gray->csMode = 0;
  197.         
  198.     err = kGDXErrNoError ;                                            // Everything Okay
  199.             
  200. ErrorExit:
  201.  
  202.     return (err);
  203. }
  204.  
  205.  
  206.  
  207. //=====================================================================================================
  208. //
  209. // GraphicsCoreGetInterrupt()
  210. //    This returns 'csMode = 0' if VBL interrupts are enabled and a value of 1 if
  211. //    VBL interrupts are disabled.
  212. //
  213. //=====================================================================================================
  214. GDXErr GraphicsCoreGetInterrupt(VDFlagRecord *flag)
  215. {
  216.  
  217.     GDXErr err = kGDXErrUnknownError;                                // Assume failure
  218.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData() ;
  219.             
  220.     if (coreData->interruptsEnabled)        
  221.         flag->csMode = 0;                                            // Report interrupts enabled
  222.     else
  223.         flag->csMode = 1;                                            // Report interrupts disabled
  224.  
  225.     err = kGDXErrNoError ;                                            // Everything Okay
  226.         
  227. ErrorExit:
  228.  
  229.     return (err);
  230. }
  231.  
  232.  
  233.  
  234. //=====================================================================================================
  235. //
  236. // GraphicsCoreGetGamma()
  237. //    This returns a pointer to the current gamma table.  The calling application cannot preallocate
  238. //    memory because of the unknown size requirements of the gamma data structure.
  239. //
  240. //=====================================================================================================
  241. GDXErr GraphicsCoreGetGamma(VDGammaRecord *gamma)
  242. {
  243.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData() ;
  244.     GDXErr err = kGDXErrUnknownError;                                // Assume failure
  245.  
  246.     if (NULL == coreData->gammaTable)
  247.         gamma->csGTable = NULL;                                        // No gamma table in use
  248.     else
  249.         gamma->csGTable = (Ptr) coreData->gammaTable;                // Return Ptr to gamma table
  250.         
  251.     err = kGDXErrNoError ;                                            // Everything Okay
  252.         
  253. ErrorExit:
  254.  
  255.     return (err);
  256. }
  257.  
  258.  
  259.  
  260. //=====================================================================================================
  261. //
  262. // GraphicsCoreGetCurrentMode()
  263. //    This is used to gather information about the current display mode.
  264. //    When called, this routine fills out a VDSwitchInfoRec with the appropriate data.
  265. //
  266. //    The Display Manager also uses the cscGetCurMode status request to determine whether a graphics
  267. //    driver supports the Display Manager. If the driver returns the 'statusErr', system software assumes
  268. //    that the driver does not support the Display Manager.
  269. //
  270. //    For this routine, the relevant fields of the 'VDSwitchInfoRec' structure are as follows:
  271. //            <-    csMode            relative depthmode of the current pixel depth
  272. //            <-    csData            DisplayModeID for the current resolution
  273. //            <-    csPage            number of the current video page (0 based)
  274. //            <-    csBaseAddr        base address of page specified in the csPage field
  275. //
  276. //=====================================================================================================
  277. GDXErr GraphicsCoreGetCurrentMode(VDSwitchInfoRec *switchInfo)
  278. {
  279.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData() ;
  280.     GDXErr err = kGDXErrUnknownError;                                // Assume failure
  281.     
  282.     // Return the current depth mode, display mode, page, and base address.
  283.     
  284.     switchInfo->csMode = (UInt16) coreData->depthMode;
  285.     switchInfo->csData = (UInt32) coreData->displayModeID;
  286.     switchInfo->csPage = (UInt16) coreData->currentPage;
  287.     switchInfo->csBaseAddr = coreData->baseAddress;
  288.     
  289.     err = kGDXErrNoError ;                                            // Everything Okay
  290.         
  291. ErrorExit:
  292.  
  293.     return (err);
  294. }
  295.  
  296.  
  297.  
  298. //=====================================================================================================
  299. //
  300. // GraphicsCoreGetSync()
  301. //    Multipurpose call to 
  302. //    1) Report the capabilities of the frame buffer in controlling the sync lines and if HW can
  303. //    "sync" on Red, Green or Blue
  304. //    2) Report the current status of the sync lines and if HW is "syncing" on Red, Green or Blue
  305. //    
  306. //    If the display supported the VESA Device Power Management Standard (DPMS), it would respond
  307. //    to HSync and VSync in the following manner:
  308. //    The VESA Standards are:
  309. //    
  310. //    State           Vert Sync        Hor Sync        Video
  311. //    -----            --------        ---------        ------
  312. //    Active             Pulses          Pulses          Active
  313. //    Standby            Pulses           No Pulses          Blanked
  314. //    Idle            No Pulses          Pulses            Blanked
  315. //    Off                 No Pulses        No Pulses        Blanked
  316. //
  317. //
  318. //
  319. //    For this routine, the relevant fields of the 'VDSyncInfoRec' structure are as follows:
  320. //            <>    csMode        Report HW capability or current state.
  321. //
  322. //                If csMode == 0xFF, then report the cabability of the HW
  323. //                When reporting the capability of the HW, set the appropriate bits of csMode:
  324. //                kDisableHorizontalSyncBit        Set if HW can disable Horizontal Sync
  325. //                kDisableVerticalSyncBit            Set if HW can disable Vertical Sync
  326. //                kDisableCompositeSyncBit        Set if HW can disable Composite Sync
  327. //                kSyncOnRedEnableBit                Set if HW can sync on Red
  328. //                kSyncOnGreenEnableBit            Set if HW can sync on Green
  329. //                kSyncOnBlueEnableBit            Set if HW can sync on Blue
  330. //                kNoSeparateSyncControlBit        Set if HW CANNOT enable/disable H,V,C sync independently
  331. //                                                Means that HW ONLY supports the VESA "OFF" state
  332. //
  333. //                If csMode == 0, then report the current state of sync lines and  if HW is
  334. //                "syncing" on Red, Green or Blue
  335. //                Reporting the "current state of the sync lines" means: "Report the State of the Display"
  336. //                To report the current state of the display, the kDisableHorizontalSyncBit and
  337. //                the kDisableVerticalSyncBit have the following values:
  338. //
  339. //                State           kDisableVerticalSyncBit        kDisableHorizontalSyncBit        Video
  340. //                -----            -----------------------        -------------------------        ------
  341. //                Active                     0                              0                          Active
  342. //                Standby                    0                           1                              Blanked
  343. //                Idle                    1                              0                        Blanked
  344. //                Off                         1                            1                        Blanked
  345. //
  346. //                To report if HW is "syncing" on Red, Green or Blue:
  347. //                kEnableSyncOnBlue                Set if HW is "syncing" on Blue
  348. //                kEnableSyncOnGreen                Set if HW is "syncing" on Blue
  349. //                kEnableSyncOnRed                Set if HW is "syncing" on Blue
  350. //
  351. //
  352. //=====================================================================================================
  353. GDXErr GraphicsCoreGetSync(VDSyncInfoRec *sync)
  354. {
  355.     GDXErr err = kGDXErrUnknownError;                    // Assume failure
  356.     Boolean getHardwareSyncCapability;                    // True if HAL should report HW cabapability.
  357.  
  358.     switch (sync->csMode)
  359.     {
  360.         case 0xff:
  361.             getHardwareSyncCapability = true;
  362.             break;
  363.         case 0:
  364.             getHardwareSyncCapability = false;
  365.             break;
  366.         default:
  367.             err = kGDXErrInvalidParameters;
  368.             goto ErrorExit;
  369.             break;
  370.     }
  371.     
  372.     err = GraphicsHALGetSync(getHardwareSyncCapability, sync);                        
  373.         
  374. ErrorExit:
  375.  
  376.     return (err);
  377. }
  378.  
  379.  
  380.  
  381. //=====================================================================================================
  382. //
  383. // GraphicsCoreGetConnection()
  384. //    This is used to gather information about the display capabilities of the display attached to the
  385. //    graphics device.  The driver must return information in the VDDisplayConnectInfoRec.
  386. //
  387. //    For this routine, the relevant fields of the 'VDDisplayConnectInfoRec' structure are as follows:
  388. //            <-    csDisplayCode    Type of connected display.
  389. //            <-    csConnectFlags    Whether the display modes for display are required or optional.
  390. //                                default is 0.  Forces the DisplayMgr to call GetModeTiming for each
  391. //                                timing mode.
  392. //
  393. //=====================================================================================================
  394. GDXErr GraphicsCoreGetConnection(VDDisplayConnectInfoRec *displayConnectInfo)
  395. {
  396.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData() ;
  397.     GDXErr err = kGDXErrUnknownError;                                // Assume failure
  398.  
  399.     RawSenseCode rawSenseCode;
  400.     ExtendedSenseCode extendedSenseCode;
  401.     Boolean standardInterpretation;    
  402.     
  403.     // Default to all modes invalid.
  404.     // Specifically, this means the 'kAllModesValid' and 'kAllModesSafe' bits of the 'csConnectFlags'
  405.     // field are set to 0.
  406.     // This forces the DisplayMgr to call GetModeTiming status calls for each timing mode, instead of
  407.     // assuming they all have the same state.
  408.  
  409.     displayConnectInfo->csConnectFlags = 0;    
  410.  
  411.     switch (coreData->displayCode)
  412.     {
  413.         case (kDisplayCode21InchMono):
  414.             displayConnectInfo->csDisplayType = kMonoTwoPageConnect;
  415.             displayConnectInfo->csConnectFlags |= ( 1 << kIsMonoDev);
  416.             break;
  417.         case (kDisplayCodePortraitMono):
  418.             displayConnectInfo->csDisplayType = kFullPageConnect;
  419.             displayConnectInfo->csConnectFlags |= ( 1 << kIsMonoDev);
  420.             break;
  421.         case (kDisplayCodePortrait):
  422.             displayConnectInfo->csDisplayType = kFullPageConnect;
  423.             break;
  424.         case (kDisplayCodeStandard):
  425.             displayConnectInfo->csDisplayType = kHRConnect;
  426.             break;
  427.         case (kDisplayCodeVGA):
  428.             displayConnectInfo->csDisplayType = kVGAConnect;
  429.             break;
  430.         case (kDisplayCodeNTSC):
  431.             displayConnectInfo->csDisplayType = kNTSCConnect;
  432.             break;
  433.         case (kDisplayCodePAL):
  434.             displayConnectInfo->csDisplayType = kPALConnect;
  435.             break;
  436.         case (kDisplayCodeMultiScanBand1):
  437.             displayConnectInfo->csDisplayType = kMultiModeCRT1Connect;
  438.             break;
  439.         case (kDisplayCodeMultiScanBand2):
  440.             displayConnectInfo->csDisplayType = kMultiModeCRT2Connect;
  441.             break;
  442.         case (kDisplayCodeMultiScanBand3):
  443.             displayConnectInfo->csDisplayType = kMultiModeCRT3Connect;
  444.             break;
  445.         case (kDisplayCode16Inch):
  446.             displayConnectInfo->csDisplayType = kColor16Connect;
  447.             break;
  448.         case (kDisplayCode19Inch):
  449.             displayConnectInfo->csDisplayType = kColor19Connect;
  450.             break;
  451.         case (kDisplayCode21Inch):
  452.             displayConnectInfo->csDisplayType = kColorTwoPageConnect;
  453.             break;
  454.         default:
  455.             displayConnectInfo->csDisplayType = kFixedModeCRTConnect;    
  456.             break;
  457.     }
  458.     
  459.  
  460.     // Report any tagging that is occurring.  Tagging is used by the DisplayMgr to help determine
  461.     // which display is associated with a particular driver.  If possible, the DisplayMgr instructs
  462.     // the display to 'wiggle' its sense lines, and then makes multiple GetConnection() calls to 
  463.     // the various graphics drivers.  The DisplayMgr considers a 'tag' to have occurred if the
  464.     // 'csConnectTaggedType' or 'csConnectTaggedData' fields change state.
  465.     // A 'tag' is considered 'standard' if the 'csConnectTaggedType' and 'csConnectTaggedData' fields
  466.     // correspond to the RawSenseCode and ExtendedSenseCode, respectively, of 'standard' sense line
  467.     // hardware implementations.
  468.     
  469.     displayConnectInfo->csConnectFlags |= ( 1 << kReportsTagging);        // Driver can report tagging
  470.     
  471.     // Get the state of the sense lines, so the Display Manager can determine if they are 'wiggling'
  472.     err = GraphicsHALGetSenseCodes(&rawSenseCode, &extendedSenseCode, &standardInterpretation);
  473.     if (err)
  474.         goto ErrorExit;
  475.     
  476.     displayConnectInfo->csConnectTaggedType = rawSenseCode;
  477.     displayConnectInfo->csConnectTaggedData = extendedSenseCode;
  478.     
  479.     if (!standardInterpretation)
  480.         displayConnectInfo->csConnectFlags |= ( 1 << kTaggingInfoNonStandard);
  481.         
  482.     err = kGDXErrNoError ;                                            // Everything Okay
  483.         
  484. ErrorExit:
  485.  
  486.     return (err);
  487. }
  488.  
  489.  
  490.  
  491. //=====================================================================================================
  492. //
  493. // GraphicsCoreGetModeTiming()
  494. //    This is used to to gather scan timing information.  The Core fills out the csTimingData, the
  495. //    mapping of DisplayModeIDs -> csTimingData is invariant for all HALs.  The HAL fills in the
  496. //    csTimingFlags.
  497. //
  498. //    For this routine, the relevant fields of the 'VDTimingInfoRec' structure are as follows:
  499. //            ->    csTimingMode    DisplayModeID describing the display resolution and scan timing
  500. //
  501. //            <-    csTimingFormat    Format of info in csTimingData field (only 'kDeclROMTables' is valid)
  502. //            <-    csTimingData    Scan timings for the DisplayModeID specified in csTimingMode
  503. //
  504. //            <-    csTimingFlags    Whether the DisplayModeID with these scan timings is required or 
  505. //                                optional.  The HAL fills this in.
  506. //
  507. //=====================================================================================================
  508. GDXErr GraphicsCoreGetModeTiming(VDTimingInfoRec *timingInfo)
  509. {
  510.  
  511.     // Define a new type which is a table of supported 'DisplayModeIDs' and their corresponding
  512.     // timingdata (the "Timing Mode constants")
  513.     
  514.     typedef struct TimingModeTable TimingModeTable;
  515.     struct TimingModeTable
  516.     {
  517.         DisplayModeID displayModeID;
  518.         UInt32 timingData;
  519.     };
  520.     
  521.     enum  {kMaxTimingModeTableEntries = 24};
  522.  
  523.     TimingModeTable timingModeTable[kMaxTimingModeTableEntries] =
  524.     {
  525.         {kDisplay512x384At60HzNTSC,     timingAppleNTSC_ST},
  526.         {kDisplay512x384At60Hz,            timingApple_512x384_60hz},
  527.  
  528.         {kDisplay640x480At50HzPAL,         timingApplePAL_ST},
  529.         {kDisplay640x480At60HzNTSC,        timingAppleNTSC_FF},
  530.         {kDisplay640x480At60HzVGA,        timingVESA_640x480_60hz},
  531.         {kDisplay640x480At67Hz,            timingApple_640x480_67hz},
  532.         {kDisplay640x870At75Hz,            timingApple_640x870_75hz},
  533.  
  534.         {kDisplay768x576At50HzPAL,        timingApplePAL_FF},
  535.         {kDisplay800x600At56HzVGA,        timingVESA_800x600_56hz},        
  536.         {kDisplay800x600At60HzVGA,        timingVESA_800x600_60hz},        
  537.         {kDisplay800x600At72HzVGA,        timingVESA_800x600_72hz},        
  538.         {kDisplay800x600At75HzVGA,        timingVESA_800x600_75hz},        
  539.         {kDisplay832x624At75Hz,            timingApple_832x624_75hz},
  540.         {kDisplay1024x768At60HzVGA,        timingVESA_1024x768_60hz},
  541.         {kDisplay1024x768At72HzVGA,        timingVESA_1024x768_70hz},    // Close enough mapping
  542.         {kDisplay1024x768At75HzVGA,        timingVESA_1024x768_75hz},
  543.         {kDisplay1024x768At75Hz,        timingApple_1024x768_75hz},
  544.         
  545.         {kDisplay1152x870At75Hz,        timingApple_1152x870_75hz},
  546.  
  547.         {kDisplay1280x960At75Hz,        timingVESA_1280x960_75hz},
  548.         {kDisplay1280x1024At75Hz,        timingVESA_1280x1024_75hz},
  549.         
  550.         {kDisplay256x192At60HzNTSCZoom,    timingAppleNTSC_ST},
  551.         {kDisplay320x240At50HzPALZoom,    timingApplePAL_ST},
  552.         {kDisplay320x240At60HzNTSCZoom,    timingAppleNTSC_FF},
  553.         {kDisplay384x288At50HzPALZoom,    timingApplePAL_FF},
  554.     };
  555.  
  556.     GDXErr err = kGDXErrInvalidParameters;                        // Assume failure    
  557.     UInt32 i;                                                    // Omnipresent loop iterator
  558.     
  559.     DisplayModeID displayModeID = (DisplayModeID) timingInfo->csTimingMode;
  560.     
  561.  
  562.     timingInfo->csTimingData = timingInvalid;                    // Default when a monitor doesn't 
  563.                                                                 // supports a given DisplayModeID
  564.  
  565.     // Scan the timingModeTable to map the DisplayModeID to a "Timing Mode Constant"
  566.     
  567.     for (i = 0; i < kMaxTimingModeTableEntries; i++)
  568.     {
  569.         if (timingModeTable[i].displayModeID == displayModeID)
  570.         {
  571.                 timingInfo->csTimingData = timingModeTable[i].timingData;
  572.                 err = kGDXErrNoError;
  573.                 break;
  574.         }
  575.     }
  576.  
  577.     if (err)
  578.         goto ErrorExit;
  579.             
  580.     err = GraphicsHALGetModeTiming(timingInfo->csTimingMode, &timingInfo->csTimingFormat, 
  581.         &timingInfo->csTimingFlags);
  582.  
  583.         
  584. ErrorExit:
  585.  
  586.     return (err);
  587. }
  588.  
  589.  
  590.  
  591. //=====================================================================================================
  592. //
  593. // GraphicsCoreGetPreferredConfiguration()
  594. //    This call is the counterpart to the SetPreferredConfiguration control all.
  595. //
  596. //    For this routine, the relevant fields of the 'VDSwitchInfoRec' structure are as follows:
  597. //        <-            csMode        DepthMode of preferred resolution
  598. //        <-            csData        DisplayModeID of preferred resolution
  599. //
  600. //=====================================================================================================
  601. GDXErr GraphicsCoreGetPreferredConfiguration(VDSwitchInfoRec *switchInfo)
  602. {
  603.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData() ;
  604.     GDXErr err = kGDXErrUnknownError;                                // Assume failure
  605.  
  606.     GraphicsPreferred graphicsPreferred;
  607.  
  608.  
  609.     // Find the preferred configuration property that has been saved and get
  610.     //         1) the preferred displayModeID
  611.     //         2) the preferred depthMode
  612.  
  613.     err = GraphicsOSSGetCorePref(&coreData->regEntryID, &graphicsPreferred);
  614.     
  615.     if (err)
  616.         goto ErrorExit;
  617.  
  618.     switchInfo->csMode = graphicsPreferred.depthMode;
  619.     switchInfo->csData = graphicsPreferred.displayModeID;
  620.     
  621.     err = kGDXErrNoError ;                                            // Everything Okay
  622.         
  623. ErrorExit:
  624.  
  625.     return (err);
  626. }
  627.  
  628.  
  629.  
  630. //=====================================================================================================
  631. //
  632. // GraphicsCoreGetNextResolution()
  633. //    This call is used to determine the set of resolutions that the current display and the hardware
  634. //    supports.
  635. //    The Core fills out the csHorizontalPixels, csVerticalLines, and csRefreshRate.  These don't vary
  636. //    with hardware implementations.  The HAL just returns the next supported DisplayModeID and the 
  637. //    maximum bit depth that is supported.
  638. //
  639. //    For this routine, the relevant fields of the 'VDResolutionInfoRec' structure are as follows:
  640. //            ->    csPreviousDiplayModeID
  641. //            If csPreviousDiplayModeID = kDisplayModeIDFindFirstResolution, get the first supported
  642. //            resolution.
  643. //            If csPreviousDiplayModeID = kDisplayModeIDCurrent, fill in the VDResolutionInfoRec
  644. //            structure with the current resolution's parameters.
  645. //            Otherwise, csPreviousDiplayModeID contains the previous DisplayModeID (hence its name)
  646. //            from the previous call.
  647. //
  648. //            <-    csDisplayModeID        ID of the next display mode following csPreviousDiplayModeID
  649. //            set to kDisplayModeIDNoMoreResolutions once all supported display modes have been reported
  650. //
  651. //            <-    csHorizontalPixels    # of pixels in a horizontal line
  652. //            <-    csVerticalLines        # of lines in a screen
  653. //            <-    csRefreshRate        Vertical Refresh Rate of the Screen
  654. //            <-    csMaxDepthMode        Maximum bit depth for the DisplayModeID (relative depth mode)
  655. //
  656. //=====================================================================================================
  657. GDXErr GraphicsCoreGetNextResolution(VDResolutionInfoRec *resolutionInfo)
  658. {
  659.  
  660.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData();
  661.     GDXErr err = kGDXErrUnknownError;                // Assume failure    
  662.     DisplayModeID displayModeID;                    // Flled in with next supported resolution
  663.     DepthMode maxDepthMode;                            // Max depthmode hw supports for a resolution
  664.  
  665.     UInt32 i;                                        // Loop iterator
  666.     Boolean found;                                    // 'true' if displayModeID in 'masterTable'
  667.  
  668.     DisplayModeIDData *masterTable = (DisplayModeIDData*)&coreData->masterTable;
  669.  
  670.     if (kDisplayModeIDCurrent == resolutionInfo->csPreviousDisplayModeID)
  671.     {
  672.         // Return the information about the current state.
  673.         displayModeID = coreData->displayModeID;    
  674.         err = GraphicsHALGetMaxDepthMode(displayModeID, &maxDepthMode);        
  675.     
  676.         if (err)                                                // Should NEVER be error
  677.             goto ErrorExit;
  678.     
  679.     }
  680.     else
  681.     {
  682.         err = GraphicsHALGetNextResolution(resolutionInfo->csPreviousDisplayModeID,
  683.                 &displayModeID, &maxDepthMode);
  684.                 
  685.         if (err)                    // Most probably not a Valid Resolution in csPreviousDisplayModeID
  686.             goto ErrorExit;
  687.     }
  688.     
  689.     // displayModeID now contains the resolution of interest in and maxDepthMode = max depthmode
  690.     // that the hw supports for that resolution.
  691.     
  692.     resolutionInfo->csDisplayModeID = displayModeID;
  693.     resolutionInfo->csMaxDepthMode = maxDepthMode;
  694.     
  695.     if (kDisplayModeIDNoMoreResolutions != displayModeID)
  696.     {
  697.         // Find the horizontalPixels, veritcalLines, and refreshRate for the given in displayModeID.
  698.         // Scanning the 'masterTable' should always produce a match since the 'masterTable' contains
  699.         // all known resolutions.  If no match occurs, there is some internal error.
  700.     
  701.         found = false;
  702.         for (i = 0 ; i < kMaxDisplayModeIDs ; i++)
  703.         {
  704.             if (masterTable[i].displayModeID == displayModeID)        // Found match if true
  705.             {
  706.                 found = true;            // Sanity check: we should always find a match
  707.                 
  708.                 resolutionInfo->csHorizontalPixels  = masterTable[i].horizontalPixels;
  709.                 resolutionInfo->csVerticalLines = masterTable[i].verticalLines;
  710.                 resolutionInfo->csRefreshRate = masterTable[i].refreshRate;
  711.     
  712.                 break;
  713.             }
  714.         }
  715.         
  716.         if (!found)
  717.             // If no match, some unknown internal error occurred, so indicate that.
  718.             err = kGDXErrUnknownError;
  719.     }
  720.         
  721. ErrorExit:
  722.  
  723.     return (err);
  724. }
  725.  
  726.  
  727.  
  728. //=====================================================================================================
  729. //
  730. // GraphicsCoreGetVideoParams()
  731. //    This fills out a VDVideoParameteresInfoRec structure for the appropriate DisplayModeID. 
  732. //    The core will fill out most of the data.  The HAL is asked to fill in the csPageCount,
  733. //    map the depthMode to bpp, and figure out the rowbytes from the horizontal pixels and depthMode
  734. //
  735. //    For this routine, the relevant fields of the 'VDVideoParametersInfoRec' structure are:
  736. //        -> csDisplayModeID    ID of the desired mode
  737. //        -> csdepthMode        The relative bit depth for which the info is desired
  738. //
  739. //    For this routine, the relevant fields of the 'VPBlock' structure are as follows:
  740. //        <- vpBaseOffset        Offset to page zero of video RAM
  741. //        <- vpRowBytes        Number of bytes between the start of successive rows of video memory
  742. //        <- vpBounds            BoundsRect for the video display (gives dimensions)
  743. //        <- vpVersion        PixelMap version number
  744. //        <- vpPackType        (Always 0)
  745. //        <- pPackSize        (Always 0)
  746. //        <- vpHRes            Horizontal resolution of the device (pixels per inch)
  747. //        <- vpVRes            Vertical resolution of the device (pixels per inch)
  748. //        <- vpPixelType        Defines the pixel type
  749. //        <- vpPixelSize        Number of bits in pixel
  750. //        <- vpCmpCount        Number of components in pixel
  751. //        <- vpCmpSize        Number of bits per component
  752. //        <- vpPlaneBytes        Offset from one plane to the next
  753. //
  754. //        <-    csPageCount        number of pages supported for resolution and bit depth
  755. //        <-    csDeviceType    device type: direct or CLUT.
  756. //
  757. //=====================================================================================================
  758. GDXErr GraphicsCoreGetVideoParams(VDVideoParametersInfoRec *videoParamatersInfo)
  759. {
  760.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData() ;
  761.     GDXErr err = kGDXErrDisplayModeIDUnsupported;                // Assume failure    
  762.  
  763.     DepthMode depthMode = videoParamatersInfo->csDepthMode;
  764.     DisplayModeID displayModeID = videoParamatersInfo->csDisplayModeID;    
  765.     
  766.     UInt32 bitsPerPixel;                // Ask HAL to map DepthMode into bits per pixel
  767.     SInt16 pageCount;                    // For calling GraphicsHALGetPages to determine # of pages
  768.     
  769.     SInt16 rowBytes;                    // Save rowBytes for the depthMode for the given resoltution
  770.  
  771.     DisplayModeIDData *masterTable = (DisplayModeIDData*)&coreData->masterTable;
  772.  
  773.     UInt32 i;                                            // Loop iterator
  774.  
  775.  
  776.     // Find the horizontalPixels and veritcalLines for the indicated displayModeID
  777.  
  778.     for (i = 0 ; i < kMaxDisplayModeIDs ; i++)
  779.     {
  780.         if (masterTable[i].displayModeID == displayModeID)
  781.         {
  782.             err = kGDXErrNoError;
  783.             (videoParamatersInfo->csVPBlockPtr)->vpBounds.bottom = masterTable[i].verticalLines;
  784.             (videoParamatersInfo->csVPBlockPtr)->vpBounds.right = masterTable[i].horizontalPixels;
  785.             rowBytes = masterTable[i].horizontalPixels;
  786.             break;
  787.         }
  788.     }
  789.  
  790.     if (err)
  791.         goto ErrorExit;
  792.     
  793.     // The displayModeID is supported, so fill in the rest of the depth independent data.
  794.  
  795.     (videoParamatersInfo->csVPBlockPtr)->vpBaseOffset         = 0;            // For us, it's always 0
  796.     (videoParamatersInfo->csVPBlockPtr)->vpBounds.top         = 0;            // Always 0
  797.     (videoParamatersInfo->csVPBlockPtr)->vpBounds.left         = 0;            // Always 0
  798.     // bottom, and right filled out above
  799.     (videoParamatersInfo->csVPBlockPtr)->vpVersion             = 0;            // Always 0
  800.     (videoParamatersInfo->csVPBlockPtr)->vpPackType         = 0;            // Always 0
  801.     (videoParamatersInfo->csVPBlockPtr)->vpPackSize         = 0;            // Always 0
  802.     (videoParamatersInfo->csVPBlockPtr)->vpHRes             = 0x00480000;    // Hard coded to 72 dpi
  803.     (videoParamatersInfo->csVPBlockPtr)->vpVRes             = 0x00480000;    // Hard coded to 72 dpi
  804.     (videoParamatersInfo->csVPBlockPtr)->vpPlaneBytes         = 0;            // Always 0
  805.  
  806.     // Fill in the depth dependent data
  807.      err = GraphicsHALGetPages(displayModeID, depthMode, &pageCount);
  808.     if (err)
  809.         goto ErrorExit;
  810.  
  811.     videoParamatersInfo->csPageCount = pageCount;
  812.     
  813.     err = GraphicsHALGetVideoParams(displayModeID, depthMode, &bitsPerPixel, &rowBytes);
  814.  
  815.     if (err)
  816.         goto ErrorExit;
  817.     
  818.     // Rowbytes set by GraphicsHALGetVideoParams so just set that now.
  819.     (videoParamatersInfo->csVPBlockPtr)->vpRowBytes = rowBytes;
  820.  
  821.     switch ( bitsPerPixel )
  822.     {
  823.         case 1:
  824.         case 2:
  825.         case 4:
  826.             // 1,2,4 bpp should are not supported by the GDX model.
  827.             // (Note:  it would be a no-brain should one decide to do so, though)
  828.             err = kGDXErrInvalidParameters;        
  829.             break;
  830.         case 8:
  831.             videoParamatersInfo->csDeviceType                         = clutType;
  832.             (videoParamatersInfo->csVPBlockPtr)->vpPixelType         = 0;
  833.             (videoParamatersInfo->csVPBlockPtr)->vpPixelSize         = 8;
  834.             (videoParamatersInfo->csVPBlockPtr)->vpCmpCount         = 1;
  835.             (videoParamatersInfo->csVPBlockPtr)->vpCmpSize             = 8;
  836.             break;
  837.         case 16:
  838.             videoParamatersInfo->csDeviceType                         = directType;
  839.             (videoParamatersInfo->csVPBlockPtr)->vpPixelType         = 16;
  840.             (videoParamatersInfo->csVPBlockPtr)->vpPixelSize         = 16;
  841.             (videoParamatersInfo->csVPBlockPtr)->vpCmpCount         = 3;
  842.             (videoParamatersInfo->csVPBlockPtr)->vpCmpSize             = 5;
  843.             (videoParamatersInfo->csVPBlockPtr)->vpPlaneBytes         = 0;
  844.             break;
  845.         case 32:
  846.             videoParamatersInfo->csDeviceType                         = directType;
  847.             (videoParamatersInfo->csVPBlockPtr)->vpPixelType         = 16;
  848.             (videoParamatersInfo->csVPBlockPtr)->vpPixelSize         = 32;
  849.             (videoParamatersInfo->csVPBlockPtr)->vpCmpCount         = 3;
  850.             (videoParamatersInfo->csVPBlockPtr)->vpCmpSize             = 8;
  851.             (videoParamatersInfo->csVPBlockPtr)->vpPlaneBytes         = 0;
  852.             break;
  853.         default:
  854.             err = kGDXErrInvalidParameters;                            // Invalid depth
  855.             break;
  856.     }
  857.  
  858. ErrorExit:
  859.  
  860.     return (err);
  861. }
  862.  
  863.  
  864.  
  865. //=====================================================================================================
  866. //
  867. // GraphicsCoreGetGammaInfoList()
  868. //    This status routine is called to iterate over the set of gamma tables that are applicable
  869. //    to the connected display.  Ideally, this information should not be stored in the 
  870. //    graphics driver at all, but until the system makes use of 'Display Modules' it has been
  871. //    deemed that the graphics driver should carry this around.
  872. //
  873. //        ->    csPreviousGammaTableID
  874. //        Usually, this field represents a GammaTableID and indicates that information for the
  875. //        NEXT applicable gamma table should be returned.  However, there are two special cases:
  876. //
  877. //                kGammaTableIDFindFirst == csPreviousGammaTableID
  878. //                This indicates that the iteration should start from the beginning, and the
  879. //                information corresponding to the FIRST applicable gamma table should be returned.
  880. //
  881. //                kGammaTableIDSpecific == csPreviousGammaTableID
  882. //                This is a special case that indicates the csGammaTableID field is acting as an 
  883. //                INPUT.  Specifically, csGammaTableID has a GammaTableID of the gamma table for which
  884. //                the csGammaTableSize and csGammaTableName fields should be filled out.
  885. //
  886. //        <->    csGammaTableID
  887. //        Usually, this is acting as an output.  Under these circumstances, this has the GammaTableID
  888. //        of the gamma table which the csGammaTableSize and csGammaTableName fields are describing.
  889. //
  890. //        In the event that there are no more applicable gamma tables, then kGammaTableIDNoMoreTables
  891. //        should be returned (NOTE: the csGammaTableSize and csGammaTableName are undefined in this case)
  892. //
  893. //        This acts as an input when 'kGammaTableIDSpecific == csPreviousGammaTableID' as described above.
  894. //
  895. //        <-    csGammaTableSize            Size of the gamma table in bytes
  896. //        <-    csGammaTableName            Gamma table name (c-string)
  897. //
  898. //=====================================================================================================
  899. GDXErr GraphicsCoreGetGammaInfoList(VDGetGammaListRec *getGammaList)
  900. {
  901.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData();
  902.     GDXErr err = kGDXErrUnknownError;                                // Assume failure
  903.  
  904.     GammaTableID gammaTableID;
  905.     Boolean gammaTableApplicable;
  906.     
  907.     enum {kNumberOfGammaTableIDs = 7};
  908.  
  909.     GammaTableID gammaList[kNumberOfGammaTableIDs] =
  910.     {        
  911.         kGammaTableIDFindFirst,                 // Not REALLY a gamma table, but indicates list start
  912.         
  913.         kGammaTableIDStandard,                    // Mac Standard Gamma
  914.         kGammaTableIDPageWhite,                    // Page-White Gamma
  915.         kGammaTableIDGray,                        // Mac Gray Gamma
  916.         kGammaTableIDRubik,                        // Mac RGB Gamma
  917.         kGammaTableIDNTSCPAL,                    // NTSC/PAL Gamma
  918.         kGammaTableIDCSCTFT                        // Active Matrix Color LCD Gamma
  919.     };
  920.  
  921.  
  922.     if (kGammaTableIDSpecific == getGammaList->csPreviousGammaTableID)
  923.     {
  924.     
  925.         // Information on a specific gamma table has been requested, so make sure that it
  926.         // is applicable to the the display that is connected.
  927.  
  928.         gammaTableID = getGammaList->csGammaTableID;
  929.         gammaTableApplicable = GammaTableApplicable(gammaTableID, coreData->displayCode);
  930.         
  931.         if (!gammaTableApplicable)
  932.         {
  933.             // The provided GammaTableID specified a gamma table which was not applicable to the
  934.             // connected display, so indicated a parameter error.
  935.             err = kGDXErrInvalidParameters;
  936.             goto ErrorExit;
  937.         }
  938.     } 
  939.     else 
  940.     {
  941.     
  942.         // Information on the next applicable gamma table has been been requested.  Therefore, find out
  943.         // what position the 'csPreviousGammaTableID' was in the the list, and locate the next
  944.         // applicable gamma table.
  945.         
  946.         UInt32 i;                                                // Loop control variable
  947.         UInt32 previousIDPosition = 0;                            // Position of 'csPreviousGammaTableID'
  948.         
  949.         gammaTableID = kGammaTableIDNoMoreTables;                // Assume no more matches (end-of-list)
  950.  
  951.         // Scan the 'gammaList' to find out the position of 'csPreviousGammaTableID'.  This is
  952.         // neccessary so that the 'next' applicable gamma table can be found.
  953.  
  954.         for (i = 0 ; i < kNumberOfGammaTableIDs ; i++)
  955.         {
  956.             previousIDPosition += 1;
  957.             if (getGammaList->csPreviousGammaTableID == gammaList[i])
  958.                 break;
  959.         }
  960.         
  961.         
  962.         // Continue scanning the list from the 'previousIDPosition' until an applicable gamma table is
  963.         // found.
  964.         // NOTE:  Since this loop terminates at "i < (kNumberOfGammaTableIDs - 1)", it will never
  965.         // actually be entered if the 'csPreviousGammaTableID' was the LAST in the list.
  966.         
  967.         for (i = previousIDPosition ; i < (kNumberOfGammaTableIDs - 1) ; i++)
  968.         {
  969.             gammaTableApplicable = GammaTableApplicable(gammaList[i], coreData->displayCode);
  970.             if (gammaTableApplicable)
  971.             {
  972.                 gammaTableID = gammaList[i];
  973.                 break;
  974.             }
  975.         }
  976.     }
  977.     
  978.     getGammaList->csGammaTableID = gammaTableID;                    // Return the GammaTableID
  979.     
  980.     // Call the appropriate RetriveGammaXXX function to get the size and name of the specified gamma
  981.     // table. Note that the gamma table itself is NOT retrieved, since a NULL is passed in as its
  982.     // destination pointer.
  983.     
  984.     switch (gammaTableID)
  985.     {
  986.         case kGammaTableIDNoMoreTables :                            // At the end of the list
  987.             err = kGDXErrNoError;
  988.             break;
  989.             
  990.         case kGammaTableIDStandard :
  991.             err = RetrieveGammaStandard(&getGammaList->csGammaTableSize,
  992.                     getGammaList->csGammaTableName, NULL);
  993.             break;
  994.             
  995.         case kGammaTableIDPageWhite :
  996.             err = RetrieveGammaPageWhite(&getGammaList->csGammaTableSize,
  997.                     getGammaList->csGammaTableName, NULL);
  998.             break;
  999.             
  1000.         case kGammaTableIDGray :
  1001.             err = RetrieveGammaGray(&getGammaList->csGammaTableSize,
  1002.                     getGammaList->csGammaTableName, NULL);
  1003.             break;
  1004.             
  1005.         case kGammaTableIDRubik :
  1006.             err = RetrieveGammaRubik(&getGammaList->csGammaTableSize,
  1007.                     getGammaList->csGammaTableName, NULL);
  1008.             break;
  1009.             
  1010.         case kGammaTableIDNTSCPAL :
  1011.             err = RetrieveGammaNTSCPAL(&getGammaList->csGammaTableSize,
  1012.                     getGammaList->csGammaTableName, NULL);
  1013.             break;
  1014.             
  1015.         case kGammaTableIDCSCTFT :
  1016.             err = RetrieveGammaCSCTFT(&getGammaList->csGammaTableSize,
  1017.                     getGammaList->csGammaTableName, NULL);
  1018.             break;
  1019.     }
  1020.  
  1021.  
  1022. ErrorExit:
  1023.     return(err);
  1024. }
  1025.  
  1026.  
  1027.  
  1028. //=====================================================================================================
  1029. //
  1030. // GraphicsCoreRetrieveGammaTable()
  1031. //    This routines copies the specified gamma table to the indicated location.  It is the responsibilty
  1032. //    of the caller to make sure that space has been allocated to hold the gamma table.
  1033. //        ->    csGammaGammaTableID        The specifier of the desired gamma table.
  1034. //        <-    csGammaTablePtr            Desired gamma table is copied to this location.
  1035. //
  1036. //=====================================================================================================
  1037. GDXErr GraphicsCoreRetrieveGammaTable(VDRetrieveGammaRec *retrieveGamma)
  1038. {
  1039.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData() ;
  1040.     GDXErr err = kGDXErrUnknownError;                                // Assume failure
  1041.     
  1042.  
  1043.     if (NULL == retrieveGamma->csGammaTablePtr)
  1044.     {
  1045.         err = kGDXErrInvalidParameters;                                // Can't copy table into NULL !
  1046.         goto ErrorExit;
  1047.     }
  1048.     
  1049.     // Call the appropriate RetriveGammaXXX function to get the specified gamma table.
  1050.     // Note that ONLY the gamma table itself is retrieved, since a NULL is passed in as the
  1051.     // destination pointers for the gamma table size and name.
  1052.     
  1053.     switch (retrieveGamma->csGammaTableID)
  1054.     {
  1055.         case kGammaTableIDStandard :
  1056.             err = RetrieveGammaStandard(NULL, NULL, retrieveGamma->csGammaTablePtr);
  1057.             break;
  1058.             
  1059.         case kGammaTableIDPageWhite :
  1060.             err = RetrieveGammaPageWhite(NULL, NULL, retrieveGamma->csGammaTablePtr);
  1061.             break;
  1062.             
  1063.         case kGammaTableIDGray :
  1064.             err = RetrieveGammaGray(NULL, NULL, retrieveGamma->csGammaTablePtr);
  1065.             break;
  1066.         case kGammaTableIDRubik :
  1067.             err = RetrieveGammaRubik(NULL, NULL, retrieveGamma->csGammaTablePtr);
  1068.             break;
  1069.             
  1070.         case kGammaTableIDNTSCPAL :
  1071.             err = RetrieveGammaNTSCPAL(NULL, NULL, retrieveGamma->csGammaTablePtr);
  1072.             break;
  1073.             
  1074.         case kGammaTableIDCSCTFT :
  1075.             err = RetrieveGammaCSCTFT(NULL, NULL, retrieveGamma->csGammaTablePtr);
  1076.             break;
  1077.             
  1078.         default :
  1079.             err = kGDXErrInvalidParameters;
  1080.     }
  1081.  
  1082.  
  1083. ErrorExit:
  1084.     return(err);
  1085. }
  1086.  
  1087.  
  1088.  
  1089. //=====================================================================================================
  1090. //
  1091. // GraphicsCoreSupportsHardwareCursor()
  1092. //    This call is used to determine if a hardware cursor is supported.
  1093. //
  1094. //=====================================================================================================
  1095. GDXErr GraphicsCoreSupportsHardwareCursor(VDSupportsHardwareCursorRec *supportsHardwareCursor)
  1096. {
  1097.     GDXErr err = kGDXErrUnknownError;                                // Assume failure
  1098.     Boolean hardwareCursorCapable;
  1099.  
  1100.     supportsHardwareCursor->csReserved1 = 0;
  1101.     supportsHardwareCursor->csReserved2 = 0;
  1102.     
  1103.     err = GraphicsHALSupportsHardwareCursor(&hardwareCursorCapable);
  1104.     if (err)
  1105.         goto ErrorExit;
  1106.     
  1107.     if (hardwareCursorCapable)
  1108.         supportsHardwareCursor->csSupportsHardwareCursor = 1;
  1109.     else
  1110.         supportsHardwareCursor->csSupportsHardwareCursor = 0;
  1111.     
  1112. ErrorExit:
  1113.     return(err);
  1114. }
  1115.  
  1116.  
  1117.  
  1118. //=====================================================================================================
  1119. //
  1120. // GraphicsCoreGetHardwareCursorDrawState()
  1121. //    This is used to determine the state of the hardware cursor.  Just pass the call to the HAL.
  1122. //
  1123. //=====================================================================================================
  1124. GDXErr GraphicsCoreGetHardwareCursorDrawState(VDHardwareCursorDrawStateRec *cursorDrawState)
  1125. {
  1126.     GDXErr err = kGDXErrUnknownError;                                // Assume failure
  1127.  
  1128.     cursorDrawState->csReserved1 = 0;
  1129.     cursorDrawState->csReserved2 = 0;
  1130.  
  1131.     err = GraphicsHALGetHardwareCursorDrawState (&(cursorDrawState->csCursorX),
  1132.             &(cursorDrawState->csCursorY), &(cursorDrawState->csCursorVisible),
  1133.             &(cursorDrawState->csCursorSet));
  1134.  
  1135. ErrorExit:
  1136.     return(err);
  1137. }
  1138.  
  1139.  
  1140.  
  1141. //=====================================================================================================
  1142. //
  1143. // GraphicsCoreGetPowerState()
  1144. //    The graphics hw might have the ability to to go into some kind of power saving mode.  Just
  1145. //    pass the call to the HAL.
  1146. //
  1147. //=====================================================================================================
  1148. GDXErr GraphicsCoreGetPowerState(VDPowerStateRec *vdPowerState)
  1149. {
  1150.  
  1151.     GDXErr err = kGDXErrUnknownError;                                // Assume failure
  1152.     
  1153.     err = GraphicsHALGetPowerState(vdPowerState);
  1154.         
  1155. ErrorExit:
  1156.  
  1157.     return err;
  1158. }
  1159.  
  1160.  
  1161.  
  1162. //=====================================================================================================
  1163. //
  1164. // GammaTableApplicable()
  1165. //    This private routine merely checks to see if a given gamma table is applicable to a given display.
  1166. //
  1167. //        ->    gammaTableID    Specifier of the gamma table in question.            
  1168. //        ->    displayCode        Specifier of the display in question
  1169. //
  1170. //        <-    Boolean            'true' if the specified gamma table is applicable to the specified display. 
  1171. //
  1172. //=====================================================================================================
  1173. static Boolean GammaTableApplicable(GammaTableID gammaTableID, DisplayCode displayCode)
  1174. {
  1175.     
  1176.     // Enumerate some arbitrary bit positions (and their masks) which correspond to different gamma
  1177.     // tables.  Setting a bit postion to '1' indicates that the gamma table is applicable for the
  1178.     // display in question.
  1179.     enum
  1180.     {
  1181.         kGammaTableStandardBit             = 0,
  1182.         kGammaTablePageWhiteBit         = 1,
  1183.         kGammaTableGrayBit                 = 2,
  1184.         kGammaTableRubikBit             = 3,
  1185.         kGammaTableNTSCPALBit             = 4,
  1186.         kGammaTableCSCTFTBit             = 5,
  1187.  
  1188.         kGammaTableStandardMask         = 0x01,
  1189.         kGammaTablePageWhiteMask         = 0x02,
  1190.         kGammaTableGrayMask             = 0x04,
  1191.         kGammaTableRubikMask             = 0x08,
  1192.         kGammaTableNTSCPALMask             = 0x10,
  1193.         kGammaTableCSCTFTMask             = 0x20
  1194.     };
  1195.     
  1196.     UInt32 applicableTables;
  1197.     Boolean gammaTableApplicable;
  1198.     
  1199.     
  1200.     // Set the appropriate bits in 'applicableTables' based on the display.
  1201.     // NOTE:  for 'kDisplayCodeUnknown', the only table marked as applicable is the 'Standard' one.
  1202.     switch (displayCode)
  1203.     {
  1204.         case kDisplayCode12Inch :
  1205.             applicableTables = kGammaTableRubikMask;
  1206.             break;
  1207.             
  1208.         case kDisplayCodeUnknown :
  1209.         case kDisplayCodeStandard :  
  1210.         case kDisplayCodeVGA :
  1211.             applicableTables = kGammaTableStandardMask;    
  1212.             break;
  1213.             
  1214.         case kDisplayCodePortraitMono :    
  1215.         case kDisplayCode21InchMono :
  1216.             applicableTables = kGammaTableGrayMask;
  1217.             break;
  1218.             
  1219.         case kDisplayCodePortrait :    
  1220.         case kDisplayCode16Inch :
  1221.         case kDisplayCode19Inch :    
  1222.         case kDisplayCode21Inch :
  1223.         case kDisplayCodeMultiScanBand1 :
  1224.         case kDisplayCodeMultiScanBand2 :
  1225.         case kDisplayCodeMultiScanBand3 :
  1226.             applicableTables = (kGammaTableStandardMask | kGammaTablePageWhiteMask);
  1227.             break;
  1228.         
  1229.         case kDisplayCodeNTSC :    
  1230.         case kDisplayCodePAL :
  1231.             applicableTables = kGammaTableNTSCPALMask;
  1232.             break;
  1233.     }
  1234.     
  1235.     // Check to see if the correct bit position in 'applicableTables' is set for a given GammaTableID.
  1236.     switch (gammaTableID)
  1237.     {
  1238.         case kGammaTableIDStandard :
  1239.             gammaTableApplicable = (0 != ( applicableTables & kGammaTableStandardMask ) );
  1240.             break;
  1241.  
  1242.         case kGammaTableIDPageWhite :
  1243.             gammaTableApplicable = (0 != ( applicableTables & kGammaTablePageWhiteMask ) );
  1244.             break;
  1245.  
  1246.         case kGammaTableIDGray :
  1247.             gammaTableApplicable = (0 != ( applicableTables & kGammaTableGrayMask ) );
  1248.             break;
  1249.  
  1250.         case kGammaTableIDRubik :
  1251.             gammaTableApplicable = (0 != ( applicableTables & kGammaTableRubikMask ) );
  1252.             break;
  1253.  
  1254.         case kGammaTableIDNTSCPAL :
  1255.             gammaTableApplicable = (0 != ( applicableTables & kGammaTableNTSCPALMask ) );
  1256.             break;
  1257.  
  1258.         case kGammaTableIDCSCTFT :
  1259.             gammaTableApplicable = (0 != ( applicableTables & kGammaTableCSCTFTMask ) );
  1260.             break;
  1261.             
  1262.         default:
  1263.             gammaTableApplicable = false;
  1264.     }
  1265.     
  1266.     return (gammaTableApplicable);
  1267. }
  1268.  
  1269.  
  1270.  
  1271. // ************  This is the temporary location of the gamma tables the Core knows about ***********
  1272. // Real-Soon-Now, this might be moved into a code fragment that is shared amoung the various graphics
  1273. // drivers.  It will be one of those funky real cool fragments that shares its DATA, as well as its
  1274. // code, so only one copy of the gamma tables will need to be in memory, regardless of how many
  1275. // drivers are loaded.  At that time, the gamma table data will become static data in the fragments
  1276. // heap, as opposed being allocated on the stack as it is here.
  1277. // This is left for the industrious byte-counter to implement.
  1278.  
  1279.  
  1280.  
  1281. //=====================================================================================================
  1282. //
  1283. // RetrieveGammaStandard()
  1284. //    This function retrieves the size, name, and gamma table of the 'Standard' gamma table.
  1285. //    Any combination of these can be retrieved by passing in a non-NULL pointer in the appropriate field.
  1286. //    
  1287. //        <- size        If non-NULL, then the size (in bytes) will be copied to the indicated location.
  1288. //        <- name        If non-NULL, the the name (c-string) will be copied to the indicated location.
  1289. //        <- gammaTbl    If non-NULL, then the GammaTbl will be copied to the indicated location.
  1290. //
  1291. //=====================================================================================================
  1292. static GDXErr RetrieveGammaStandard(ByteCount *size, char *name, GammaTbl *gammaTbl)
  1293. {
  1294.     ByteCount gammaTableSize;
  1295.     char gammaTableName[32] = "Mac Standard Gamma";
  1296.     
  1297.     GammaTbl gammaTable =
  1298.     {
  1299.         0,                    // 0 == gVersion
  1300.         0,                    // 0 == gType, so gamma table is display derived, not CLUT derived
  1301.         0,                    // No formula data
  1302.         1,                    // 1 == gChanCnt, so apply same correction to R, G, & B channels
  1303.         256,                // 256 entries per channel
  1304.         8,                    // 8 bits of significance per entry
  1305.         NULL                // 0 == gFormulaData[0], since it will be filled in with correction data
  1306.     };
  1307.     
  1308.     enum {kNumberOfElements = 256};
  1309.     
  1310.     UInt8 correctionData[kNumberOfElements] =
  1311.     {
  1312.         0x00, 0x05, 0x09, 0x0B, 0x0E, 0x10, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1E, 0x20, 0x22, 0x24,
  1313.         0x25, 0x27, 0x28, 0x2A, 0x2C, 0x2D, 0x2F, 0x30, 0x31, 0x33, 0x34, 0x36, 0x37, 0x38, 0x3A, 0x3B, 
  1314.         0x3C, 0x3E, 0x3F, 0x40, 0x42, 0x43, 0x44, 0x45, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4D, 0x4E, 0x4F, 
  1315.         0x50, 0x51, 0x52, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5E, 0x5F, 0x60, 0x61, 
  1316.         0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 
  1317.         0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 
  1318.         0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8C, 0x8D, 0x8E, 0x8F, 
  1319.         0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9B, 0x9C, 0x9D, 
  1320.         0x9E, 0x9F, 0xA0, 0xA1, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 
  1321.         0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 
  1322.         0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC0, 0xC1, 0xC2, 0xC3, 0xC3, 0xC4, 
  1323.         0xC5, 0xC6, 0xC7, 0xC7, 0xC8, 0xC9, 0xCA, 0xCA, 0xCB, 0xCC, 0xCD, 0xCD, 0xCE, 0xCF, 0xD0, 0xD0, 
  1324.         0xD1, 0xD2, 0xD3, 0xD3, 0xD4, 0xD5, 0xD6, 0xD6, 0xD7, 0xD8, 0xD9, 0xD9, 0xDA, 0xDB, 0xDC, 0xDC, 
  1325.         0xDD, 0xDE, 0xDF, 0xDF, 0xE0, 0xE1, 0xE1, 0xE2, 0xE3, 0xE4, 0xE4, 0xE5, 0xE6, 0xE7, 0xE7, 0xE8, 
  1326.         0xE9, 0xE9, 0xEA, 0xEB, 0xEC, 0xEC, 0xED, 0xEE, 0xEE, 0xEF, 0xF0, 0xF1, 0xF1, 0xF2, 0xF3, 0xF3, 
  1327.         0xF4, 0xF5, 0xF5, 0xF6, 0xF7, 0xF8, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC, 0xFC, 0xFD, 0xFE, 0xFF 
  1328.     };
  1329.         
  1330.     gammaTableSize = sizeof(GammaTbl)                        // Fixed sized header
  1331.             + gammaTable.gFormulaSize                        // Add formula size
  1332.             + (gammaTable.gChanCnt * gammaTable.gDataCnt)    // Assume 1 byte/entry
  1333.             - 2;                                            // Correct for gFormulaData[0] counted twice
  1334.             
  1335.     if (NULL != size)
  1336.         *size = gammaTableSize;
  1337.         
  1338.     if (NULL != name)
  1339.         CStrCopy(name, gammaTableName);
  1340.         
  1341.     if (NULL != gammaTbl)
  1342.     {
  1343.         UInt8 *destinationCorrectionData;            // Copy the correction data TO here
  1344.         UInt32 i;                                    // Loop control variable
  1345.         
  1346.         *gammaTbl = gammaTable;                        // Copy the fixed sized header of the gamma table
  1347.  
  1348.         destinationCorrectionData = (UInt8 *) &(gammaTbl->gFormulaData);
  1349.         
  1350.         for (i = 0 ; i < kNumberOfElements ; i++)
  1351.             destinationCorrectionData[i] = correctionData[i];
  1352.     }
  1353.     
  1354.     return (kGDXErrNoError);
  1355. }
  1356.  
  1357.  
  1358.  
  1359. //=====================================================================================================
  1360. //
  1361. // RetrieveGammaPageWhite()
  1362. //    This function retrieves the size, name, and gamma table of the 'Page-White' gamma table.
  1363. //    Any combination of these can be retrieved by passing in a non-NULL pointer in the appropriate field.
  1364. //    
  1365. //        <- size        If non-NULL, then the size (in bytes) will be copied to the indicated location.
  1366. //        <- name        If non-NULL, the the name (c-string) will be copied to the indicated location.
  1367. //        <- gammaTbl    If non-NULL, then the GammaTbl will be copied to the indicated location.
  1368. //
  1369. //=====================================================================================================
  1370. static GDXErr RetrieveGammaPageWhite(ByteCount *size, char *name, GammaTbl *gammaTbl)
  1371. {
  1372.     ByteCount gammaTableSize;
  1373.     char gammaTableName[32] = "Page-White Gamma";
  1374.     
  1375.     GammaTbl gammaTable =
  1376.     {
  1377.         0,                    // 0 == gVersion
  1378.         0,                    // 0 == gType, so gamma table is display derived, not CLUT derived
  1379.         0,                    // No formula data
  1380.         3,                    // 3 == gChanCnt, so apply individual correction to R, G, & B channels
  1381.         256,                // 256 entries per channel
  1382.         8,                    // 8 bits of significance per entry
  1383.         NULL                // 0 == gFormulaData[0], since it will be filled in with correction data
  1384.     };
  1385.     
  1386.     enum {kNumberOfElements = 768};        
  1387.     
  1388.     UInt8 correctionData[kNumberOfElements] =
  1389.     {
  1390.         // Red channel
  1391.         0x00, 0x03, 0x06, 0x09, 0x0C, 0x10, 0x10, 0x12, 0x13, 0x15, 0x16, 0x16, 0x18, 0x1B, 0x1C, 0x1E,    
  1392.         0x1F, 0x22, 0x23, 0x26, 0x28, 0x2B, 0x2C, 0x2F, 0x32, 0x34, 0x37, 0x3A, 0x3C, 0x3F, 0x40, 0x41,
  1393.         0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x47, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51,
  1394.         0x52, 0x53, 0x54, 0x54, 0x56, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 
  1395.         0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 
  1396.         0x71, 0x72, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 
  1397.         0x7F, 0x81, 0x82, 0x83, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8A, 0x8B, 0x8C, 0x8D, 
  1398.         0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x98, 0x99, 0x9A, 0x9B, 
  1399.         0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA1, 0xA2, 0xA3, 0xA4, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA8, 
  1400.         0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB2, 0xB3, 0xB4, 0xB5, 0xB5, 
  1401.         0xB6, 0xB7, 0xB8, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC0, 0xC1, 0xC2, 
  1402.         0xC3, 0xC3, 0xC4, 0xC5, 0xC6, 0xC6, 0xC7, 0xC8, 0xC9, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCD, 0xCE, 
  1403.         0xCF, 0xD0, 0xD1, 0xD1, 0xD2, 0xD3, 0xD4, 0xD4, 0xD5, 0xD6, 0xD7, 0xD7, 0xD8, 0xD9, 0xDA, 0xDA, 
  1404.         0xDB, 0xDC, 0xDD, 0xDE, 0xDE, 0xDF, 0xE0, 0xE1, 0xE1, 0xE2, 0xE3, 0xE4, 0xE4, 0xE5, 0xE6, 0xE7, 
  1405.         0xE7, 0xE8, 0xE9, 0xEA, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEE, 0xEF, 0xF0, 0xF1, 0xF1, 0xF2, 0xF3, 
  1406.         0xF4, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF8, 0xF9, 0xFA, 0xFB, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF, 
  1407.         
  1408.         // Green channel
  1409.         0x00, 0x03, 0x06, 0x09, 0x0C, 0x10, 0x10, 0x18, 0x20, 0x20, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28,
  1410.         0x29, 0x2C, 0x2D, 0x2E, 0x30, 0x32, 0x34, 0x37, 0x38, 0x3A, 0x3D, 0x3F, 0x40, 0x41, 0x42, 0x42, 
  1411.         0x43, 0x44, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 
  1412.         0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 
  1413.         0x62, 0x63, 0x64, 0x65, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 
  1414.         0x71, 0x71, 0x72, 0x73, 0x74, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x79, 0x7A, 0x7B, 0x7C, 0x7D,
  1415.         0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x84, 0x85, 0x86, 0x87, 0x88, 0x88, 0x89, 0x8A, 0x8B, 
  1416.         0x8C, 0x8D, 0x8E, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x93, 0x94, 0x95, 0x96, 0x96, 0x97, 0x98, 
  1417.         0x99, 0x9A, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA2, 0xA3, 0xA4, 0xA5, 
  1418.         0xA5, 0xA6, 0xA7, 0xA8, 0xA8, 0xA9, 0xAA, 0xAB, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xAF, 0xB0, 0xB1, 
  1419.         0xB2, 0xB2, 0xB3, 0xB4, 0xB5, 0xB5, 0xB6, 0xB7, 0xB7, 0xB8, 0xB9, 0xBA, 0xBA, 0xBB, 0xBC, 0xBD, 
  1420.         0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC1, 0xC2, 0xC3, 0xC3, 0xC4, 0xC5, 0xC6, 0xC6, 0xC7, 0xC8, 0xC9, 
  1421.         0xC9, 0xCA, 0xCB, 0xCC, 0xCC, 0xCD, 0xCE, 0xCF, 0xCF, 0xD0, 0xD1, 0xD2, 0xD2, 0xD3, 0xD4, 0xD4, 
  1422.         0xD5, 0xD6, 0xD6, 0xD7, 0xD8, 0xD9, 0xD9, 0xDA, 0xDB, 0xDC, 0xDC, 0xDD, 0xDE, 0xDE, 0xDF, 0xE0, 
  1423.         0xE1, 0xE1, 0xE2, 0xE3, 0xE4, 0xE4, 0xE5, 0xE6, 0xE6, 0xE7, 0xE8, 0xE9, 0xE9, 0xEA, 0xEB, 0xEC, 
  1424.         0xEC, 0xED, 0xEE, 0xEF, 0xEF, 0xF0, 0xF1, 0xF2, 0xF2, 0xF3, 0xF4, 0xF4, 0xF5, 0xF6, 0xF7, 0xF7, 
  1425.         
  1426.         // Blue channel
  1427.         0x00, 0x02, 0x05, 0x08, 0x0A, 0x0D, 0x10, 0x10, 0x10, 0x20, 0x20, 0x22, 0x23, 0x23, 0x24, 0x25,
  1428.         0x25, 0x27, 0x28, 0x29, 0x2A, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 
  1429.         0x3A, 0x3C, 0x3D, 0x3F, 0x40, 0x41, 0x41, 0x42, 0x42, 0x43, 0x44, 0x44, 0x45, 0x45, 0x46, 0x47, 
  1430.         0x47, 0x48, 0x49, 0x4A, 0x4A, 0x4B, 0x4C, 0x4D, 0x4D, 0x4E, 0x4F, 0x4F, 0x51, 0x51, 0x52, 0x53, 
  1431.         0x54, 0x55, 0x56, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x60, 0x61, 
  1432.         0x62, 0x62, 0x63, 0x64, 0x64, 0x65, 0x66, 0x66, 0x67, 0x68, 0x69, 0x69, 0x6A, 0x6B, 0x6C, 0x6C, 
  1433.         0x6D, 0x6E, 0x6F, 0x6F, 0x70, 0x71, 0x72, 0x72, 0x73, 0x74, 0x74, 0x75, 0x76, 0x77, 0x77, 0x78, 
  1434.         0x79, 0x79, 0x7A, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x82, 0x83, 0x84, 0x84, 
  1435.         0x85, 0x86, 0x86, 0x87, 0x88, 0x88, 0x89, 0x8A, 0x8A, 0x8B, 0x8C, 0x8D, 0x8D, 0x8E, 0x8F, 0x90, 
  1436.         0x90, 0x91, 0x91, 0x92, 0x93, 0x93, 0x94, 0x95, 0x95, 0x96, 0x97, 0x97, 0x98, 0x99, 0x99, 0x9A, 
  1437.         0x9B, 0x9B, 0x9C, 0x9D, 0x9D, 0x9E, 0x9F, 0xA0, 0xA0, 0xA1, 0xA1, 0xA2, 0xA3, 0xA3, 0xA4, 0xA4, 
  1438.         0xA5, 0xA6, 0xA6, 0xA7, 0xA7, 0xA8, 0xA9, 0xA9, 0xAA, 0xAB, 0xAB, 0xAC, 0xAD, 0xAD, 0xAE, 0xAF, 
  1439.         0xAF, 0xB0, 0xB0, 0xB1, 0xB2, 0xB2, 0xB3, 0xB3, 0xB4, 0xB5, 0xB5, 0xB6, 0xB6, 0xB7, 0xB8, 0xB8, 
  1440.         0xB9, 0xBA, 0xBA, 0xBB, 0xBB, 0xBC, 0xBD, 0xBD, 0xBE, 0xBF, 0xBF, 0xC0, 0xC0, 0xC1, 0xC2, 0xC2, 
  1441.         0xC3, 0xC3, 0xC4, 0xC5, 0xC5, 0xC6, 0xC6, 0xC7, 0xC8, 0xC8, 0xC9, 0xC9, 0xCA, 0xCB, 0xCB, 0xCC, 
  1442.         0xCC, 0xCD, 0xCE, 0xCE, 0xCF, 0xD0, 0xD0, 0xD1, 0xD1, 0xD2, 0xD3, 0xD3, 0xD4, 0xD4, 0xD5, 0xD6 
  1443.     };
  1444.         
  1445.     gammaTableSize = sizeof(GammaTbl)                        // Fixed sized header
  1446.             + gammaTable.gFormulaSize                        // Add formula size
  1447.             + (gammaTable.gChanCnt * gammaTable.gDataCnt)    // Assume 1 byte/entry
  1448.             - 2;                                            // Correct for gFormulaData[0] counted twice
  1449.             
  1450.     if (NULL != size)
  1451.         *size = gammaTableSize;
  1452.         
  1453.     if (NULL != name)
  1454.         CStrCopy(name, gammaTableName);
  1455.         
  1456.     if (NULL != gammaTbl)
  1457.     {
  1458.         UInt8 *destinationCorrectionData;            // Copy the correction data TO here
  1459.         UInt32 i;                                    // Loop control variable
  1460.         
  1461.         *gammaTbl = gammaTable;                        // Copy the fixed sized header of the gamma table
  1462.  
  1463.         destinationCorrectionData = (UInt8 *) &(gammaTbl->gFormulaData);
  1464.         
  1465.         for (i = 0 ; i < kNumberOfElements ; i++)
  1466.             destinationCorrectionData[i] = correctionData[i];
  1467.     }
  1468.     
  1469.     return (kGDXErrNoError);
  1470. }
  1471.  
  1472.  
  1473.  
  1474. //=====================================================================================================
  1475. //
  1476. // RetrieveGammaGray()
  1477. //    This function retrieves the size, name, and gamma table of the 'Gray' gamma table.
  1478. //    Any combination of these can be retrieved by passing in a non-NULL pointer in the appropriate field.
  1479. //    
  1480. //        <- size        If non-NULL, then the size (in bytes) will be copied to the indicated location.
  1481. //        <- name        If non-NULL, the the name (c-string) will be copied to the indicated location.
  1482. //        <- gammaTbl    If non-NULL, then the GammaTbl will be copied to the indicated location.
  1483. //
  1484. //=====================================================================================================
  1485. static GDXErr RetrieveGammaGray(ByteCount *size, char *name, GammaTbl *gammaTbl)
  1486. {
  1487.     ByteCount gammaTableSize;
  1488.     char gammaTableName[32] = "Mac Gray Gamma";
  1489.     
  1490.     GammaTbl gammaTable =
  1491.     {
  1492.         0,                    // 0 == gVersion
  1493.         0,                    // 0 == gType, so gamma table is display derived, not CLUT derived
  1494.         0,                    // No formula data
  1495.         1,                    // 1 == gChanCnt, so apply same correction to R, G, & B channels
  1496.         256,                // 256 entries per channel
  1497.         8,                    // 8 bits of significance per entry
  1498.         NULL                // 0 == gFormulaData[0], since it will be filled in with correction data
  1499.     };
  1500.     
  1501.     enum {kNumberOfElements = 256};
  1502.     
  1503.     UInt8 correctionData[kNumberOfElements] =
  1504.     {
  1505.         0x05, 0x07, 0x08, 0x09, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x12, 0x14, 0x15, 0x16, 0x18, 0x19,
  1506.         0x1A, 0x1C, 0x1D, 0x1E, 0x20, 0x21, 0x22, 0x23, 0x24, 0x26, 0x28, 0x29, 0x2A, 0x2C, 0x2D, 0x2F,
  1507.         0x30, 0x31, 0x33, 0x34, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3C, 0x3D, 0x3E, 0x40, 0x41, 0x42, 0x43,
  1508.         0x44, 0x45, 0x46, 0x48, 0x49, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55,
  1509.         0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x63, 0x63, 0x65, 0x65, 0x67,
  1510.         0x67, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
  1511.         0x78, 0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x81, 0x82, 0x83, 0x83, 0x84, 0x85, 0x86,
  1512.         0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8E, 0x90, 0x90, 0x91, 0x92, 0x93, 0x93, 0x94,
  1513.         0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA0, 0xA1, 0xA2, 0xA3,
  1514.         0xA4, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAA, 0xAC, 0xAD, 0xAD, 0xAE, 0xAE, 0xB0, 0xB1,
  1515.         0xB2, 0xB3, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
  1516.         0xBF, 0xC0, 0xC1, 0xC2, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD,
  1517.         0xCD, 0xCE, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD3, 0xD4, 0xD5, 0xD6, 0xD6, 0xD7, 0xD8, 0xD8,
  1518.         0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDE, 0xDF, 0xE0, 0xE1, 0xE1, 0xE2, 0xE3, 0xE4, 0xE4, 0xE5,
  1519.         0xE6, 0xE7, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEE, 0xEF, 0xEF, 0xF0, 0xF1, 0xF2,
  1520.         0xF3, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF8, 0xF9, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
  1521.     };
  1522.         
  1523.     gammaTableSize = sizeof(GammaTbl)                        // Fixed sized header
  1524.             + gammaTable.gFormulaSize                        // Add formula size
  1525.             + (gammaTable.gChanCnt * gammaTable.gDataCnt)    // Assume 1 byte/entry
  1526.             - 2;                                            // Correct for gFormulaData[0] counted twice
  1527.             
  1528.     if (NULL != size)
  1529.         *size = gammaTableSize;
  1530.         
  1531.     if (NULL != name)
  1532.         CStrCopy(name, gammaTableName);
  1533.         
  1534.     if (NULL != gammaTbl)
  1535.     {
  1536.         UInt8 *destinationCorrectionData;            // Copy the correction data TO here
  1537.         UInt32 i;                                    // Loop control variable
  1538.         
  1539.         *gammaTbl = gammaTable;                        // Copy the fixed sized header of the gamma table
  1540.  
  1541.         destinationCorrectionData = (UInt8 *) &(gammaTbl->gFormulaData);
  1542.         
  1543.         for (i = 0 ; i < kNumberOfElements ; i++)
  1544.             destinationCorrectionData[i] = correctionData[i];
  1545.     }
  1546.     
  1547.     return (kGDXErrNoError);
  1548. }
  1549.  
  1550.  
  1551.  
  1552. //=====================================================================================================
  1553. //
  1554. // RetrieveGammaRubik()
  1555. //    This function retrieves the size, name, and gamma table of the 'Rubik' gamma table.
  1556. //    Any combination of these can be retrieved by passing in a non-NULL pointer in the appropriate field.
  1557. //    
  1558. //        <- size        If non-NULL, then the size (in bytes) will be copied to the indicated location.
  1559. //        <- name        If non-NULL, the the name (c-string) will be copied to the indicated location.
  1560. //        <- gammaTbl    If non-NULL, then the GammaTbl will be copied to the indicated location.
  1561. //
  1562. //=====================================================================================================
  1563. static GDXErr RetrieveGammaRubik(ByteCount *size, char *name, GammaTbl *gammaTbl)
  1564. {
  1565.     ByteCount gammaTableSize;
  1566.     char gammaTableName[32] = "Mac RGB Gamma";
  1567.     
  1568.     GammaTbl gammaTable =
  1569.     {
  1570.         0,                    // 0 == gVersion
  1571.         0,                    // 0 == gType, so gamma table is display derived, not CLUT derived
  1572.         0,                    // No formula data
  1573.         1,                    // 1 == gChanCnt, so apply same correction to R, G, & B channels
  1574.         256,                // 256 entries per channel
  1575.         8,                    // 8 bits of significance per entry
  1576.         NULL                // 0 == gFormulaData[0], since it will be filled in with correction data
  1577.     };
  1578.     
  1579.     enum {kNumberOfElements = 256};
  1580.     
  1581.     UInt8 correctionData[kNumberOfElements] =
  1582.     {
  1583.         0x05, 0x07, 0x08, 0x09, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x12, 0x14, 0x15, 0x16, 0x18, 0x19,
  1584.         0x1A, 0x1C, 0x1D, 0x1E, 0x20, 0x21, 0x22, 0x23, 0x24, 0x26, 0x28, 0x29, 0x2A, 0x2C, 0x2D, 0x2F,
  1585.         0x30, 0x31, 0x33, 0x34, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3C, 0x3D, 0x3E, 0x40, 0x41, 0x42, 0x43,
  1586.         0x44, 0x45, 0x46, 0x48, 0x49, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55,
  1587.         0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x63, 0x63, 0x65, 0x65, 0x67,
  1588.         0x67, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
  1589.         0x78, 0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x81, 0x82, 0x83, 0x83, 0x84, 0x85, 0x86,
  1590.         0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8E, 0x90, 0x90, 0x91, 0x92, 0x93, 0x93, 0x94,
  1591.         0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA0, 0xA1, 0xA2, 0xA3,
  1592.         0xA4, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAA, 0xAC, 0xAD, 0xAD, 0xAE, 0xAE, 0xB0, 0xB1,
  1593.         0xB2, 0xB3, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
  1594.         0xBF, 0xC0, 0xC1, 0xC2, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD,
  1595.         0xCD, 0xCE, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD3, 0xD4, 0xD5, 0xD6, 0xD6, 0xD7, 0xD8, 0xD8,
  1596.         0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDE, 0xDF, 0xE0, 0xE1, 0xE1, 0xE2, 0xE3, 0xE4, 0xE4, 0xE5,
  1597.         0xE6, 0xE7, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEE, 0xEF, 0xEF, 0xF0, 0xF1, 0xF2,
  1598.         0xF3, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF8, 0xF9, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
  1599.     };
  1600.         
  1601.     gammaTableSize = sizeof(GammaTbl)                        // Fixed sized header
  1602.             + gammaTable.gFormulaSize                        // Add formula size
  1603.             + (gammaTable.gChanCnt * gammaTable.gDataCnt)    // Assume 1 byte/entry
  1604.             - 2;                                            // Correct for gFormulaData[0] counted twice
  1605.             
  1606.     if (NULL != size)
  1607.         *size = gammaTableSize;
  1608.         
  1609.     if (NULL != name)
  1610.         CStrCopy(name, gammaTableName);
  1611.         
  1612.     if (NULL != gammaTbl)
  1613.     {
  1614.         UInt8 *destinationCorrectionData;            // Copy the correction data TO here
  1615.         UInt32 i;                                    // Loop control variable
  1616.         
  1617.         *gammaTbl = gammaTable;                        // Copy the fixed sized header of the gamma table
  1618.  
  1619.         destinationCorrectionData = (UInt8 *) &(gammaTbl->gFormulaData);
  1620.         
  1621.         for (i = 0 ; i < kNumberOfElements ; i++)
  1622.             destinationCorrectionData[i] = correctionData[i];
  1623.     }
  1624.     
  1625.     return (kGDXErrNoError);
  1626. }
  1627.  
  1628.  
  1629.  
  1630. //=====================================================================================================
  1631. //
  1632. // RetrieveGammaNTSCPAL()
  1633. //    This function retrieves the size, name, and gamma table of the 'NTSC/PAL' gamma table.
  1634. //    Any combination of these can be retrieved by passing in a non-NULL pointer in the appropriate field.
  1635. //    
  1636. //        <- size        If non-NULL, then the size (in bytes) will be copied to the indicated location.
  1637. //        <- name        If non-NULL, the the name (c-string) will be copied to the indicated location.
  1638. //        <- gammaTbl    If non-NULL, then the GammaTbl will be copied to the indicated location.
  1639. //
  1640. //    This gamma table serves two functions:  it scales the full range (0-255) graphics values to CCIR601
  1641. //    range (16-235) and adds gamma correction factor of 1.4.  The values
  1642. //    were derived knowing that:
  1643. //    
  1644. //        255^(1/1.4) * (scale factor) + 16 = 235
  1645. //        
  1646. //    Therefore, the scale factor = 4.183.  Hence, the values for the CLUT are as follows:
  1647. //        
  1648. //        value = N^(1/1.4) * 4.183 + 16
  1649. //    
  1650. //    where N is the 8 bit linear input from VRAM for the Red, Green, or Blue component.
  1651. //        
  1652. //=====================================================================================================
  1653. static GDXErr RetrieveGammaNTSCPAL(ByteCount *size, char *name, GammaTbl *gammaTbl)
  1654. {
  1655.     ByteCount gammaTableSize;
  1656.     char gammaTableName[32] = "NTSC/PAL Gamma";
  1657.     
  1658.     GammaTbl gammaTable =
  1659.     {
  1660.         0,                    // 0 == gVersion
  1661.         0,                    // 0 == gType, so gamma table is display derived, not CLUT derived
  1662.         0,                    // No formula data
  1663.         1,                    // 1 == gChanCnt, so apply same correction to R, G, & B channels
  1664.         256,                // 256 entries per channel
  1665.         8,                    // 8 bits of significance per entry
  1666.         NULL                // 0 == gFormulaData[0], since it will be filled in with correction data
  1667.     };
  1668.     
  1669.     enum {kNumberOfElements = 256};        
  1670.     
  1671.     UInt8 correctionData[kNumberOfElements] =
  1672.     {
  1673.         0x10, 0x14, 0x17, 0x19, 0x1B, 0x1D, 0x1F, 0x21, 0x22, 0x24, 0x26, 0x27, 0x29, 0x2A, 0x2C, 0x2D,
  1674.         0x2E, 0x30, 0x31, 0x32, 0x34, 0x35, 0x36, 0x37, 0x38, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x41, 
  1675.         0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 
  1676.         0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 
  1677.         0x62, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 
  1678.         0x70, 0x71, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7B, 0x7C, 
  1679.         0x7D, 0x7E, 0x7F, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x85, 0x86, 0x87, 0x87, 0x88, 0x89, 
  1680.         0x8A, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8E, 0x8F, 0x90, 0x91, 0x91, 0x92, 0x93, 0x94, 0x94, 0x95, 
  1681.         0x96, 0x97, 0x97, 0x98, 0x99, 0x9A, 0x9A, 0x9B, 0x9C, 0x9D, 0x9D, 0x9E, 0x9F, 0x9F, 0xA0, 0xA1, 
  1682.         0xA2, 0xA2, 0xA3, 0xA4, 0xA4, 0xA5, 0xA6, 0xA7, 0xA7, 0xA8, 0xA9, 0xA9, 0xAA, 0xAB, 0xAC, 0xAC, 
  1683.         0xAD, 0xAE, 0xAE, 0xAF, 0xB0, 0xB0, 0xB1, 0xB2, 0xB3, 0xB3, 0xB4, 0xB5, 0xB5, 0xB6, 0xB7, 0xB7, 
  1684.         0xB8, 0xB9, 0xB9, 0xBA, 0xBB, 0xBB, 0xBC, 0xBD, 0xBD, 0xBE, 0xBF, 0xBF, 0xC0, 0xC1, 0xC1, 0xC2, 
  1685.         0xC3, 0xC3, 0xC4, 0xC5, 0xC5, 0xC6, 0xC7, 0xC7, 0xC8, 0xC9, 0xC9, 0xCA, 0xCB, 0xCB, 0xCC, 0xCD, 
  1686.         0xCD, 0xCE, 0xCF, 0xCF, 0xD0, 0xD1, 0xD1, 0xD2, 0xD3, 0xD3, 0xD4, 0xD4, 0xD5, 0xD6, 0xD6, 0xD7, 
  1687.         0xD8, 0xD8, 0xD9, 0xDA, 0xDA, 0xDB, 0xDB, 0xDC, 0xDD, 0xDD, 0xDE, 0xDF, 0xDF, 0xE0, 0xE0, 0xE1, 
  1688.         0xE2, 0xE2, 0xE3, 0xE4, 0xE4, 0xE5, 0xE5, 0xE6, 0xE7, 0xE7, 0xE8, 0xE9, 0xE9, 0xEA, 0xEA, 0xEB
  1689.     };
  1690.         
  1691.     gammaTableSize = sizeof(GammaTbl)                        // Fixed sized header
  1692.             + gammaTable.gFormulaSize                        // Add formula size
  1693.             + (gammaTable.gChanCnt * gammaTable.gDataCnt)    // Assume 1 byte/entry
  1694.             - 2;                                            // Correct for gFormulaData[0] counted twice
  1695.             
  1696.     if (NULL != size)
  1697.         *size = gammaTableSize;
  1698.         
  1699.     if (NULL != name)
  1700.         CStrCopy(name, gammaTableName);
  1701.         
  1702.     if (NULL != gammaTbl)
  1703.     {
  1704.         UInt8 *destinationCorrectionData;            // Copy the correction data TO here
  1705.         UInt32 i;                                    // Loop control variable
  1706.         
  1707.         *gammaTbl = gammaTable;                        // Copy the fixed sized header of the gamma table
  1708.  
  1709.         destinationCorrectionData = (UInt8 *) &(gammaTbl->gFormulaData);
  1710.         
  1711.         for (i = 0 ; i < kNumberOfElements ; i++)
  1712.             destinationCorrectionData[i] = correctionData[i];
  1713.     }
  1714.     
  1715.     return (kGDXErrNoError);
  1716. }
  1717.  
  1718.  
  1719.  
  1720. //=====================================================================================================
  1721. //
  1722. // RetrieveGammaCSCTFT()
  1723. //    This function retrieves the size, name, and gamma table of the 'CSCTFT' gamma table.
  1724. //    Any combination of these can be retrieved by passing in a non-NULL pointer in the appropriate field.
  1725. //    
  1726. //        <- size        If non-NULL, then the size (in bytes) will be copied to the indicated location.
  1727. //        <- name        If non-NULL, the the name (c-string) will be copied to the indicated location.
  1728. //        <- gammaTbl    If non-NULL, then the GammaTbl will be copied to the indicated location.
  1729. //
  1730. //=====================================================================================================
  1731. static GDXErr RetrieveGammaCSCTFT(ByteCount *size, char *name, GammaTbl *gammaTbl)
  1732. {
  1733.     ByteCount gammaTableSize;
  1734.     char gammaTableName[32] = "Active Color LCD Gamma";
  1735.     
  1736.     GammaTbl gammaTable =
  1737.     {
  1738.         0,                    // 0 == gVersion
  1739.         0,                    // 0 == gType, so gamma table is display derived, not CLUT derived
  1740.         0,                    // No formula data
  1741.         1,                    // 1 == gChanCnt, so apply same correction to R, G, & B channels
  1742.         256,                // 256 entries per channel
  1743.         8,                    // 8 bits of significance per entry
  1744.         NULL                // 0 == gFormulaData[0], since it will be filled in with correction data
  1745.     };
  1746.     
  1747.     enum {kNumberOfElements = 256};
  1748.     
  1749.     UInt8 correctionData[kNumberOfElements] =
  1750.     {
  1751.         0x00, 0x05, 0x09, 0x0B, 0x0E, 0x10, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1E, 0x20, 0x22, 0x24, 
  1752.         0x25, 0x28, 0x28, 0x2A, 0x2C, 0x2D, 0x2F, 0x30, 0x31, 0x33, 0x34, 0x36, 0x37, 0x38, 0x3A, 0x3B, 
  1753.         0x3C, 0x3E, 0x3F, 0x42, 0x44, 0x48, 0x49, 0x4A, 0x4B, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x54, 
  1754.         0x55, 0x56, 0x57, 0x58, 0x59, 0x59, 0x5A, 0x5A, 0x5B, 0x5C, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 
  1755.         0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 
  1756.         0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x7A, 0x7C, 0x7E, 0x80, 0x82, 0x84, 0x86, 0x87, 0x88, 0x8A, 
  1757.         0x8C, 0x8E, 0x90, 0x92, 0x94, 0x96, 0x98, 0x99, 0x9A, 0x9B, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 
  1758.         0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xA9, 0xAA, 0xAA, 0xAB, 0xAB, 0xAB, 0xAC, 
  1759.         0xAC, 0xAD, 0xAD, 0xAE, 0xAE, 0xAF, 0xAF, 0xB0, 0xB0, 0xB0, 0xB1, 0xB1, 0xB2, 0xB2, 0xB3, 0xB3, 
  1760.         0xB4, 0xB4, 0xB4, 0xB5, 0xB5, 0xB6, 0xB6, 0xB7, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBC, 0xBD, 
  1761.         0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC8, 0xC9, 0xC9, 0xCA, 0xCA, 
  1762.         0xCA, 0xCB, 0xCB, 0xCC, 0xCD, 0xCD, 0xCD, 0xCE, 0xCE, 0xCF, 0xCF, 0xD0, 0xD0, 0xD1, 0xD2, 0xD3, 
  1763.         0xD3, 0xD4, 0xD4, 0xD5, 0xD5, 0xD6, 0xD6, 0xD7, 0xD7, 0xD8, 0xD9, 0xD9, 0xDA, 0xDB, 0xDC, 0xDC, 
  1764.         0xDD, 0xDE, 0xDF, 0xDF, 0xE0, 0xE1, 0xE1, 0xE2, 0xE3, 0xE4, 0xE4, 0xE5, 0xE6, 0xE7, 0xE7, 0xE8, 
  1765.         0xE9, 0xE9, 0xEA, 0xEA, 0xEB, 0xEB, 0xEC, 0xEC, 0xED, 0xED, 0xEE, 0xEE, 0xEE, 0xEF, 0xEF, 0xF0, 
  1766.         0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFC, 0xFD, 0xFE, 0xFF
  1767.     };
  1768.         
  1769.     gammaTableSize = sizeof(GammaTbl)                        // Fixed sized header
  1770.             + gammaTable.gFormulaSize                        // Add formula size
  1771.             + (gammaTable.gChanCnt * gammaTable.gDataCnt)    // Assume 1 byte/entry
  1772.             - 2;                                            // Correct for gFormulaData[0] counted twice
  1773.             
  1774.     if (NULL != size)
  1775.         *size = gammaTableSize;
  1776.         
  1777.     if (NULL != name)
  1778.         CStrCopy(name, gammaTableName);
  1779.         
  1780.     if (NULL != gammaTbl)
  1781.     {
  1782.         UInt8 *destinationCorrectionData;            // Copy the correction data TO here
  1783.         UInt32 i;                                    // Loop control variable
  1784.         
  1785.         *gammaTbl = gammaTable;                        // Copy the fixed sized header of the gamma table
  1786.  
  1787.         destinationCorrectionData = (UInt8 *) &(gammaTbl->gFormulaData);
  1788.         
  1789.         for (i = 0 ; i < kNumberOfElements ; i++)
  1790.             destinationCorrectionData[i] = correctionData[i];
  1791.     }
  1792.     
  1793.     return (kGDXErrNoError);
  1794. }
  1795.  
  1796.